/* Copyright (c) 2009, Michael Patraw
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * The name of Michael Patraw may not be used to endorse or promote
 *       products derived from this software without specific prior written
 *       permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Michael Patraw ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Michael Patraw BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef AT_H
#define AT_H

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************************************\

ATLIB DEFINES

\******************************************************************************/

#define AT_DEFAULT_CELL_WIDTH  8
#define AT_DEFAULT_CELL_HEIGHT 13

#define atTrue 1
#define atFalse 0

#define AT_FG 0
#define AT_BG 1

/******************************************************************************\

ATLIB TYPES

\******************************************************************************/

typedef int atBool_T;

typedef struct atSurface_T atSurface_T;
typedef struct atGlyphs_T atGlyphs_T;

typedef struct atColor_T {
    unsigned char r, g, b;
} atColor_T;

typedef void (*atEventCallback_T) (void);

/******************************************************************************\

ATLIB CONSTANTS

\******************************************************************************/

/* Standard terminal colors.
 */
extern const atColor_T ATC_STDBLACK;
extern const atColor_T ATC_STDBLUE;
extern const atColor_T ATC_STDCYAN;
extern const atColor_T ATC_STDGREEN;
extern const atColor_T ATC_STDMAGENTA;
extern const atColor_T ATC_STDRED;
extern const atColor_T ATC_STDWHITE;
extern const atColor_T ATC_STDYELLOW;

/* Additional colors.
 */
extern const atColor_T ATC_ALICEBLUE;
extern const atColor_T ATC_ANTIQUEWHITE;
extern const atColor_T ATC_AQUA;
extern const atColor_T ATC_AQUAMARINE;
extern const atColor_T ATC_AZURE;
extern const atColor_T ATC_BEIGE;
extern const atColor_T ATC_BISQUE;
extern const atColor_T ATC_BLACK;
extern const atColor_T ATC_BLANCHEDALMOND;
extern const atColor_T ATC_BLUE;
extern const atColor_T ATC_BLUEVIOLET;
extern const atColor_T ATC_BROWN;
extern const atColor_T ATC_BURLYWOOD;
extern const atColor_T ATC_CADETBLUE;
extern const atColor_T ATC_CHARTREUSE;
extern const atColor_T ATC_CHOCOLATE;
extern const atColor_T ATC_CORAL;
extern const atColor_T ATC_CORNFLOWERBLUE;
extern const atColor_T ATC_CORNSILK;
extern const atColor_T ATC_CRIMSON;
extern const atColor_T ATC_CYAN;
extern const atColor_T ATC_DARKBLUE;
extern const atColor_T ATC_DARKCYAN;
extern const atColor_T ATC_DARKGOLDENROD;
extern const atColor_T ATC_DARKGRAY;
extern const atColor_T ATC_DARKGREY;
extern const atColor_T ATC_DARKGREEN;
extern const atColor_T ATC_DARKKHAKI;
extern const atColor_T ATC_DARKMAGENTA;
extern const atColor_T ATC_DARKOLIVEGREEN;
extern const atColor_T ATC_DARKORANGE;
extern const atColor_T ATC_DARKORCHID;
extern const atColor_T ATC_DARKRED;
extern const atColor_T ATC_DARKSALMON;
extern const atColor_T ATC_DARKSEAGREEN;
extern const atColor_T ATC_DARKSLATEBLUE;
extern const atColor_T ATC_DARKSLATEGRAY;
extern const atColor_T ATC_DARKSLATEGREY;
extern const atColor_T ATC_DARKTURQUOISE;
extern const atColor_T ATC_DARKVIOLET;
extern const atColor_T ATC_DEEPPINK;
extern const atColor_T ATC_DEEPSKYBLUE;
extern const atColor_T ATC_DIMGRAY;
extern const atColor_T ATC_DIMGREY;
extern const atColor_T ATC_DODGERBLUE;
extern const atColor_T ATC_FIREBRICK;
extern const atColor_T ATC_FLORALWHITE;
extern const atColor_T ATC_FORESTGREEN;
extern const atColor_T ATC_FUCHSIA;
extern const atColor_T ATC_GAINSBORO;
extern const atColor_T ATC_GHOSTWHITE;
extern const atColor_T ATC_GOLD;
extern const atColor_T ATC_GOLDENROD;
extern const atColor_T ATC_GRAY;
extern const atColor_T ATC_GREY;
extern const atColor_T ATC_GREEN;
extern const atColor_T ATC_GREENYELLOW ;
extern const atColor_T ATC_HONEYDEW;
extern const atColor_T ATC_HOTPINK;
extern const atColor_T ATC_INDIANRED;
extern const atColor_T ATC_INDIGO;
extern const atColor_T ATC_IVORY;
extern const atColor_T ATC_KHAKI;
extern const atColor_T ATC_LAVENDER;
extern const atColor_T ATC_LAVENDERBLUSH;
extern const atColor_T ATC_LAWNGREEN;
extern const atColor_T ATC_LEMONCHIFFON;
extern const atColor_T ATC_LIGHTBLUE;
extern const atColor_T ATC_LIGHTCORAL;
extern const atColor_T ATC_LIGHTCYAN;
extern const atColor_T ATC_LIGHTGOLDENRODYELLOW;
extern const atColor_T ATC_LIGHTGRAY;
extern const atColor_T ATC_LIGHTGREY;
extern const atColor_T ATC_LIGHTGREEN;
extern const atColor_T ATC_LIGHTPINK;
extern const atColor_T ATC_LIGHTSALMON;
extern const atColor_T ATC_LIGHTSEAGREEN;
extern const atColor_T ATC_LIGHTSKYBLUE;
extern const atColor_T ATC_LIGHTSLATEGRAY;
extern const atColor_T ATC_LIGHTSLATEGREY;
extern const atColor_T ATC_LIGHTSTEELBLUE;
extern const atColor_T ATC_LIGHTYELLOW;
extern const atColor_T ATC_LIME;
extern const atColor_T ATC_LIMEGREEN;
extern const atColor_T ATC_LINEN;
extern const atColor_T ATC_MAGENTA;
extern const atColor_T ATC_MAROON;
extern const atColor_T ATC_MEDIUMAQUAMARINE;
extern const atColor_T ATC_MEDIUMBLUE;
extern const atColor_T ATC_MEDIUMORCHID;
extern const atColor_T ATC_MEDIUMPURPLE;
extern const atColor_T ATC_MEDIUMSEAGREEN;
extern const atColor_T ATC_MEDIUMSLATEBLUE;
extern const atColor_T ATC_MEDIUMSPRINGGREEN;
extern const atColor_T ATC_MEDIUMTURQUOISE;
extern const atColor_T ATC_MEDIUMVIOLETRED;
extern const atColor_T ATC_MIDNIGHTBLUE;
extern const atColor_T ATC_MINTCREAM;
extern const atColor_T ATC_MISTYROSE;
extern const atColor_T ATC_MOCCASIN;
extern const atColor_T ATC_NAVAJOWHITE;
extern const atColor_T ATC_NAVY;
extern const atColor_T ATC_OLDLACE;
extern const atColor_T ATC_OLIVE;
extern const atColor_T ATC_OLIVEDRAB;
extern const atColor_T ATC_ORANGE;
extern const atColor_T ATC_ORANGERED;
extern const atColor_T ATC_ORCHID;
extern const atColor_T ATC_PALEGOLDENROD;
extern const atColor_T ATC_PALEGREEN;
extern const atColor_T ATC_PALETURQUOISE;
extern const atColor_T ATC_PALEVIOLETRED;
extern const atColor_T ATC_PAPAYAWHIP;
extern const atColor_T ATC_PEACHPUFF;
extern const atColor_T ATC_PERU;
extern const atColor_T ATC_PINK;
extern const atColor_T ATC_PLUM;
extern const atColor_T ATC_POWDERBLUE;
extern const atColor_T ATC_PURPLE;
extern const atColor_T ATC_RED;
extern const atColor_T ATC_ROSYBROWN;
extern const atColor_T ATC_ROYALBLUE;
extern const atColor_T ATC_SADDLEBROWN;
extern const atColor_T ATC_SALMON;
extern const atColor_T ATC_SANDYBROWN;
extern const atColor_T ATC_SEAGREEN;
extern const atColor_T ATC_SEASHELL;
extern const atColor_T ATC_SIENNA;
extern const atColor_T ATC_SILVER;
extern const atColor_T ATC_SKYBLUE;
extern const atColor_T ATC_SLATEBLUE;
extern const atColor_T ATC_SLATEGRAY;
extern const atColor_T ATC_SLATEGREY;
extern const atColor_T ATC_SNOW;
extern const atColor_T ATC_SPRINGGREEN;
extern const atColor_T ATC_STEELBLUE;
extern const atColor_T ATC_TAN;
extern const atColor_T ATC_TEAL;
extern const atColor_T ATC_THISTLE;
extern const atColor_T ATC_TOMATO;
extern const atColor_T ATC_TURQUOISE;
extern const atColor_T ATC_VIOLET;
extern const atColor_T ATC_WHEAT;
extern const atColor_T ATC_WHITE;
extern const atColor_T ATC_WHITESMOKE;
extern const atColor_T ATC_YELLOW;
extern const atColor_T ATC_YELLOWGREEN;

/******************************************************************************\

ATLIB ENUMERATIONS

\******************************************************************************/

/* Key events, mapped direction to SDL keys.
 */
enum {
    ATK_NONE    = -1,

    ATK_BACKSPACE  = 8,
    ATK_TAB        = 9,
    ATK_CLEAR      = 12,
    ATK_RETURN     = 13,
    ATK_PAUSE      = 19,
    ATK_ESCAPE     = 27,
    ATK_SPACE      = 32,
    ATK_EXCLAIM    = 33,
    ATK_QUOTEDBL   = 34,
    ATK_HASH       = 35,
    ATK_DOLLAR     = 36,
    ATK_AMPERSAND  = 38,
    ATK_QUOTE      = 39,
    ATK_LEFTPAREN  = 40,
    ATK_RIGHTPAREN = 41,
    ATK_ASTERISK   = 42,
    ATK_PLUS       = 43,
    ATK_COMMA      = 44,
    ATK_MINUS      = 45,
    ATK_PERIOD     = 46,
    ATK_SLASH      = 47,
    ATK_0          = 48,
    ATK_1          = 49,
    ATK_2          = 50,
    ATK_3          = 51,
    ATK_4          = 52,
    ATK_5          = 53,
    ATK_6          = 54,
    ATK_7          = 55,
    ATK_8          = 56,
    ATK_9          = 57,
    ATK_COLON      = 58,
    ATK_SEMICOLON  = 59,
    ATK_LESS       = 60,
    ATK_EQUALS     = 61,
    ATK_GREATER    = 62,
    ATK_QUESTION   = 63,
    ATK_AT         = 64,

    ATK_LEFTBRACKET  = 91,
    ATK_BACKSLASH    = 92,
    ATK_RIGHTBRACKET = 93,
    ATK_CARET        = 94,
    ATK_UNDERSCORE   = 95,
    ATK_BACKQUOTE    = 96,
    ATK_a            = 97,
    ATK_b            = 98,
    ATK_c            = 99,
    ATK_d            = 100,
    ATK_e            = 101,
    ATK_f            = 102,
    ATK_g            = 103,
    ATK_h            = 104,
    ATK_i            = 105,
    ATK_j            = 106,
    ATK_k            = 107,
    ATK_l            = 108,
    ATK_m            = 109,
    ATK_n            = 110,
    ATK_o            = 111,
    ATK_p            = 112,
    ATK_q            = 113,
    ATK_r            = 114,
    ATK_s            = 115,
    ATK_t            = 116,
    ATK_u            = 117,
    ATK_v            = 118,
    ATK_w            = 119,
    ATK_x            = 120,
    ATK_y            = 121,
    ATK_z            = 122,
    ATK_DELETE       = 127,

    ATK_KP0             = 256,
    ATK_KP1             = 257,
    ATK_KP2             = 258,
    ATK_KP3             = 259,
    ATK_KP4             = 260,
    ATK_KP5             = 261,
    ATK_KP6             = 262,
    ATK_KP7             = 263,
    ATK_KP8             = 264,
    ATK_KP9             = 265,
    ATK_KP_PERIOD       = 266,
    ATK_KP_DIVIDE       = 267,
    ATK_KP_MULTIPLY     = 268,
    ATK_KP_MINUS        = 269,
    ATK_KP_PLUS         = 270,
    ATK_KP_ENTER        = 271,
    ATK_KP_EQUALS       = 272,

    ATK_UP              = 273,
    ATK_DOWN            = 274,
    ATK_RIGHT           = 275,
    ATK_LEFT            = 276,
    ATK_INSERT          = 277,
    ATK_HOME            = 278,
    ATK_END             = 279,
    ATK_PAGEUP          = 280,
    ATK_PAGEDOWN        = 281,

    ATK_F1              = 282,
    ATK_F2              = 283,
    ATK_F3              = 284,
    ATK_F4              = 285,
    ATK_F5              = 286,
    ATK_F6              = 287,
    ATK_F7              = 288,
    ATK_F8              = 289,
    ATK_F9              = 290,
    ATK_F10             = 291,
    ATK_F11             = 292,
    ATK_F12             = 293,
    ATK_F13             = 294,
    ATK_F14             = 295,
    ATK_F15             = 296,

    ATK_NUMLOCK         = 300,
    ATK_CAPSLOCK        = 301,
    ATK_SCROLLOCK       = 302,
    ATK_RSHIFT          = 303,
    ATK_LSHIFT          = 304,
    ATK_RCTRL           = 305,
    ATK_LCTRL           = 306,
    ATK_RALT            = 307,
    ATK_LALT            = 308,
    ATK_RMETA           = 309,
    ATK_LMETA           = 310,
    ATK_LSUPER          = 311,
    ATK_RSUPER          = 312,
    ATK_MODE            = 313,
    ATK_COMPOSE         = 314,

    ATK_HELP            = 315,
    ATK_PRINT           = 316,
    ATK_SYSREQ          = 317,
    ATK_BREAK           = 318,
    ATK_MENU            = 319,
    ATK_POWER           = 320,
    ATK_EURO            = 321,
    ATK_UNDO            = 322,

    ATK_LAST
};

/* Key modifiers.
 */
enum {
    ATMOD_NONE   = 0x0000,
	ATMOD_LSHIFT = 0x0001,
	ATMOD_RSHIFT = 0x0002,
	ATMOD_SHIFT  = ATMOD_LSHIFT | ATMOD_RSHIFT,
	ATMOD_LCTRL  = 0x0040,
	ATMOD_RCTRL  = 0x0080,
	ATMOD_CTRL   = ATMOD_LCTRL | ATMOD_RCTRL,
	ATMOD_LALT   = 0x0100,
	ATMOD_RALT   = 0x0200,
	ATMOD_ALT    = ATMOD_LALT | ATMOD_RALT,
	ATMOD_LMETA  = 0x0400,
	ATMOD_RMETA  = 0x0800,
	ATMOD_NUM    = 0x1000,
	ATMOD_CAPS   = 0x2000,
	ATMOD_MODE   = 0x4000
};

/* Enumeration of possible mouse buttons.
 */
enum {
    ATM_LEFT       = 0x000001,
    ATM_MIDDLE     = 0x000002,
    ATM_RIGHT      = 0x000004,
    ATM_WHEEL_UP   = 0x000008,
    ATM_WHEEL_DOWN = 0x000010
};

/******************************************************************************\

ATLIB FUNCTIONS

\******************************************************************************/

/* Set/get cell size.
 */
extern void atSetCellSize(int w, int h);
extern void atGetCellSize(int *w, int *h);

/* Set color and glyphs.
 */
extern void atSetColor(int i, atColor_T c);
extern void atSwapColor(int i, int j);
extern atColor_T atGetColor(int i);
extern void atSetGlyphs(atGlyphs_T *glyphs);

/* Main functions.
 */
extern atBool_T atStart(const char *title, int w, int h);
extern void atStop(void);
extern unsigned long atTicks(void);
extern void atDelay(unsigned long ms);
extern void atToggleFullScreen(void);
extern void atSetTitle(const char * title);
extern void atKill(void);
extern void atRevive(void);
extern atSurface_T *atMainSurface(void);
extern void atUpdate(void);

/* Drawing
 */
extern void atDrawCell(atSurface_T *s, int x, int y);
extern void atDrawGlyph(atSurface_T *s, int x, int y, int colormax, int pos);
extern void atDrawString(atSurface_T *s, int x, int y, int colormax, const char *str);

/* Glyph creation functions.
 */
extern atGlyphs_T *atNewGlyphs(int capacity, int gw, int gh);
extern void atDelGlyphs(atGlyphs_T *g);
extern void atGetGlyphSize(atGlyphs_T *g, int *w, int *h);
extern int atGetGlyphsCapacity(atGlyphs_T *g);
extern void atSetGlyphScale(atGlyphs_T *g, int s);
extern int atGetGlyphScale(atGlyphs_T *g);
extern void atSetGlyphAt(atGlyphs_T *g, int pos, const int *glyph);
extern int *atGetGlyphAt(atGlyphs_T *g, int pos);

extern atGlyphs_T *atDefaultGlyphs(void);

/* Surface functions.
 */
extern atSurface_T *atNewSurface(int w, int h);
extern atSurface_T *atLoadBMP(const char *filename);
extern void atDelSurface(atSurface_T *s);
extern void atGetSurfaceSize(atSurface_T *s, int *w, int*h);
extern atColor_T atGetSurfaceBG(atSurface_T *s);
extern void atSetSurfaceBG(atSurface_T *s, atColor_T c);
extern void atSetSurfaceColorKey(atSurface_T *s, atColor_T c);
extern void atSetSurfaceAlpha(atSurface_T *s, unsigned char val);
extern void atBlitSurface(atSurface_T *dst, int x, int y, atSurface_T *src,
    int sx, int sy, int sw, int sh);
extern void atClearSurface(atSurface_T *s);

/* Turns key repeat on/off.
 */
extern void atKeyRepeat(atBool_T yesno);

/* Updates the event variables.
 */
extern void atGrabEvents(void);

/* Event access.
 */
extern atBool_T atKeyPressed(void);
extern int atKey(void);
extern int atKeyMod(void);

extern atBool_T atMousePressed(void);
extern int atMouseButton(void);
extern int atMouseX(void);
extern int atMouseY(void);
extern int atMouseDX(void);
extern int atMouseDY(void);

extern atBool_T atClosed(void);

/* Setting event callbacks.
 */
extern void atSetOnMousePress(atEventCallback_T cb);
extern void atSetOnMouseRelease(atEventCallback_T cb);
extern void atSetOnMouseMotion(atEventCallback_T cb);
extern void atSetOnMouseDrag(atEventCallback_T cb);
extern void atSetOnKeyPress(atEventCallback_T cb);
extern void atSetOnKeyRelease(atEventCallback_T cb);
extern void atSetOnQuit(atEventCallback_T cb);

/* 
 */

#ifdef __cplusplus
}
#endif

#endif /* AT_H */
